use std::str::FromStr;

use once_cell::sync::Lazy;
use urlencoding::decode;
use wither::bson::oid::ObjectId;
/// ## parse_url_query_params
/// 将 a=b&c=d 解析为 `[("a","b"),("c","d")]`
pub fn parse_url_query_params<'a>(
    mut query_str: &'a str,
) -> Box<dyn Iterator<Item = (String, String)> + 'a> {
    if query_str.chars().next().unwrap_or_default() == '?' {
        query_str = &query_str[1..];
    }
    Box::new(query_str.split('&').filter_map(|item| {
        let mut split_item = item.split('=');
        let pair = (split_item.next(), split_item.next());
        pair.0?;
        let key = pair.0.unwrap();
        let key = decode(<&str>::clone(&key))
            .ok()
            .unwrap_or_else(|| key.to_string());
        let value = pair.1.map(decode).and_then(Result::ok).unwrap_or_default();
        Some((key, value))
    }))
}

/// ## string_to_object_id
/// 转换string到object_id，如果转换失败则None
pub fn string_to_object_id<T: AsRef<str>>(s: T) -> Option<ObjectId> {
    ObjectId::from_str(s.as_ref()).ok()
}
thread_local! {
    static JIE_BA: Lazy<jieba_rs::Jieba> = Lazy::new(jieba_rs::Jieba::new);
}

#[inline]
pub fn text_cut_all(s: &str) -> String {
    JIE_BA.with(|j| j.cut_all(s)).join(" ")
}

#[inline]
pub fn text_cut_for_search(s: &str) -> String {
    JIE_BA.with(|j| j.cut_for_search(s, true)).join(" ")
}

#[cfg(test)]
mod test {
    use super::*;
    use std::collections::HashMap;
    use urlencoding::encode;
    #[test]
    fn test_text_cut() {
        println!("{}", text_cut_all("微光网络工作室"));
    }

    #[test]
    fn test_parse_url_query_params_1() {
        let res = parse_url_query_params("a=b&c=d").collect::<HashMap<_, _>>();
        assert_eq!(res.get("a").unwrap(), "b");
        assert_eq!(res.get("c").unwrap(), "d");
    }
    #[test]
    fn test_parse_url_query_params_2() {
        let res = parse_url_query_params(
            format!("?a=b&c=d&我=你&{}={}", encode("你"), encode("他")).as_str(),
        )
        .collect::<HashMap<_, _>>();
        assert_eq!(res.get("a").unwrap(), "b");
        assert_eq!(res.get("c").unwrap(), "d");
        assert_eq!(res.get("我").unwrap(), "你");
        assert_eq!(res.get("你").unwrap(), "他");
    }
}
